# coding: utf-8


class WheatstonBridge():
    
    def __init__(self, resistor_1, resistor_2, resistor_3, resistor_x, voltage_source: float=3.3):
        self.resistor_1 = resistor_1
        self.resistor_2 = resistor_2
        self.resistor_3 = resistor_3
        self.resistor_x = resistor_x
        
        self.voltage_source = voltage_source

    def get_voltage_output(self, resistor_x: float=None, resistor_2: float=None):
        if resistor_x:
            self.resistor_x = resistor_x
        if resistor_2:
            self.resistor_2 = resistor_2
        return self.get_voltage_B_point() - self.get_voltage_D_point()

    def get_voltage_D_point(self):
        
        return self.voltage_source * (self.resistor_2 / (self.resistor_2 + self.resistor_1))
    
    def get_voltage_B_point(self):
        
        return self.voltage_source * (self.resistor_x / (self.resistor_3 + self.resistor_x))

    def get_current_output(self):
        
        current_1 = (self.voltage_source - self.get_voltage_D_point()) / self.resistor_1
        current_2 = self.get_voltage_D_point() / self.resistor_2
        current_3 = (self.voltage_source - self.get_voltage_B_point()) / self.resistor_3
        current_x = self.get_voltage_B_point() / self.resistor_x
        
        return current_1, current_2, current_3, current_x

if __name__ == '__main__':
    
    from tqdm import trange
    import matplotlib.pyplot as plt
    import numpy as np
    
    wb = WheatstonBridge(5e3, 5e3, 5e3, 5e3)
    
    voltage_output = []
    potentiometer = [5, 500]
    one_step = 1
    
    current_list = []
    
    for i in trange(int(potentiometer[0]), int(potentiometer[1]), one_step, desc='Voltage Output Calculating...'):
        voltage_output.append(wb.get_voltage_output(resistor_x=(i+5e3)) * 1e3)
        current_list.append(wb.get_current_output())
    
    fig, ax1 = plt.subplots()
    ax2 = ax1.twinx()
    
    ax1.plot(np.arange(int(potentiometer[0]), int(potentiometer[1]), one_step), voltage_output, 'ro', markersize=1, alpha=0.5)
    ax1.legend(['$V_g$'])
    
    ax2.plot(np.arange(int(potentiometer[0]), int(potentiometer[1]), one_step), [i[3] * 1e6 for i in current_list], 'c-', markersize=1, alpha=0.5)
    ax2.legend(['$I_x$'])
    
    ax1.set_xlabel('Resistor ($Ohm$)')
    ax1.set_ylabel('Voltage Output ($mV$)')
    ax2.set_ylabel('Current Output ($uA$)')
    
    plt.title('$V_g$ and $I$ in relation to $R_x$ in a Wheatstone Bridge Circuit ($R_4 = 5K\ Ohm$)')
    plt.grid()
    plt.show()